package com.xinzhitong.www.service.impl;

import com.xinzhitong.www.exception.BusyException;
import com.xinzhitong.www.exception.ReceiptPlaceException;
import com.xinzhitong.www.exception.receiptplace.NoSuchReceiptPlaceException;
import com.xinzhitong.www.exception.receiptplace.ReceiptPlaceEmptyException;
import com.xinzhitong.www.exception.receiptplace.ReceiptPlaceIncompleteException;
import com.xinzhitong.www.mapper.ReceiptPlaceMapper;
import com.xinzhitong.www.pojo.ReceiptPlace;
import com.xinzhitong.www.pojo.User;
import com.xinzhitong.www.service.ReceiptPlaceService;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.lang.reflect.Field;
import java.util.List;

/**
 * 收货地址服务实现类
 *
 * @author 徐鑫
 */
@Service
@Transactional
public class ReceiptPlaceServiceImpl implements ReceiptPlaceService {

    @Resource
    ReceiptPlaceMapper receiptPlaceMapper;

    @Override
    public List<ReceiptPlace> getUsersReceiptPlaces() {
        Subject subject = SecurityUtils.getSubject();
        User user = (User) subject.getPrincipal();
        List<ReceiptPlace> receiptPlaces = receiptPlaceMapper.selectReceiptPlaceFrom(user.getUsername());
        if (receiptPlaces == null || receiptPlaces.size() == 0)
            throw new ReceiptPlaceEmptyException();
        return receiptPlaces;
    }

    @Override
    public void addAReceiptPlace(ReceiptPlace receiptPlace) {
        Subject subject = SecurityUtils.getSubject();
        User user = (User) subject.getPrincipal();
        receiptPlace.setUsername(user.getUsername());

        //检查收货地址所有的值
        if (receiptPlaceIsInvalid(receiptPlace))
            throw new ReceiptPlaceIncompleteException();
        Integer res = receiptPlaceMapper.insertReceiptPlace(receiptPlace);
        if (res == 0)
            throw new BusyException();
    }

    @Override
    public ReceiptPlace getTheReceiptPlaceOf(Integer id) throws ReceiptPlaceException {
        Subject subject = SecurityUtils.getSubject();
        User user = (User) subject.getPrincipal();
        ReceiptPlace receiptPlace = receiptPlaceMapper.selectTheReceiptPlace(id, user.getUsername());
        if (receiptPlace == null)
            throw new NoSuchReceiptPlaceException();
        return receiptPlace;
    }

    @Override
    public void editTheReceiptPlace(ReceiptPlace receiptPlace) throws ReceiptPlaceException {
        Subject subject = SecurityUtils.getSubject();
        User user = (User) subject.getPrincipal();
        receiptPlace.setUsername(user.getUsername());
        if (receiptPlaceIsInvalid(receiptPlace))
            throw new ReceiptPlaceIncompleteException();
        ReceiptPlace tmp = receiptPlaceMapper.selectTheReceiptPlace(receiptPlace.getId(), user.getUsername());
        if (tmp == null)
            throw new NoSuchReceiptPlaceException();
        if (receiptPlaceMapper.updateTheReceiptPlace(receiptPlace) == 0)
            throw new BusyException();
    }

    @Override
    public void deleteTheReceiptPlaceIn(Integer[] ids) throws ReceiptPlaceException {
        if (ids.length == 0)
            throw new ReceiptPlaceEmptyException();
        StringBuilder idsString = new StringBuilder("(");
        for (int i = 0; i < ids.length; i++) {
            if (i == 0)
                idsString.append(ids[i]);
            else
                idsString.append(", ").append(ids[i]);
        }
        idsString.append(")");
        if (receiptPlaceMapper.deleteTheReceiptPlace(idsString.toString()) == 0)
            throw new BusyException();
    }

    /**
     * 检查收货地址是否准确
     *
     * @param receiptPlace 收货地址
     * @return 是否准确
     */
    private boolean receiptPlaceIsInvalid(ReceiptPlace receiptPlace) {
        Class cls = receiptPlace.getClass();
        for (Field field : cls.getDeclaredFields()) {
            field.setAccessible(true);
            try {
                //若id以外的值为空
                if (!field.getName().equals("id") && field.get(receiptPlace) == null)
                    return true;
            } catch (IllegalAccessException e) {
                e.printStackTrace();
                throw new BusyException();
            }
        }
        return false;
    }

}
